package com.w1.security.utiles;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.w1.security.domain.LoginUser;
import io.jsonwebtoken.*;
import javafx.beans.binding.SetExpression;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;


import java.util.Base64;
import java.util.Date;
import java.util.UUID;

/**
 * @author mingyifan
 * @date 2022-02-15 14:32
 */
public class JwtUtil {
    public static final Long JWT_TTL=24*60*60*1000L*7;//七天
    public static final String JWT_KEY="sangeng";
    public static String getUUID(){
        String token = UUID.randomUUID().toString().replace("-", "");
        return token;
    }
    /**
     *  生成jwt
     *  @param subject 要存放的数据
     *  mingyifan
     *  2022/2/15 14:39
     */
    public static String createJWT(String subject){
        JwtBuilder builder=getJWTBuilder(subject,null,getUUID());
        return builder.compact();
    }
    /**
     *  生成jwt
     *  @param subject 要存放的数据
     *  @param ttlMillis token超时时间
     *  @return java.lang.String
     *  mingyifan
     *  2022/2/15 14:55
     */
    public static String createJWT(String subject,Long ttlMillis){
        JwtBuilder builder=getJWTBuilder(subject,ttlMillis,getUUID());
        return builder.compact();
    }
    /**
     *  生成jwt
     *  @param subject 要存放的数据
     *  @param ttlMillis token超时时间
     *  @param id
     *  @return java.lang.String
     *  mingyifan
     *  2022/2/15 14:55
     */
    public static String createJWT(String subject,Long ttlMillis,String id){
        JwtBuilder builder=getJWTBuilder(subject,ttlMillis,id);
        return builder.compact();
    }
    private static JwtBuilder getJWTBuilder(String subject,Long ttlMillis,String uuid){
        SignatureAlgorithm signatureAlgorithm=SignatureAlgorithm.HS256;
        SecretKey secretKey=generalKey();
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        if (ttlMillis==null){
            ttlMillis=JwtUtil.JWT_TTL;
        }
        long expMillis = nowMillis+ttlMillis;
        Date expData = new Date(expMillis);
        return Jwts.builder()
                .setId(uuid)            //唯一的id
                .setSubject(subject)    //主题 可以使json数据
                .setIssuer("sg")        //签发者
                .setIssuedAt(now) //签发时间
                .signWith(signatureAlgorithm,secretKey)  //使用hs256加密，第二个参数为密钥
                .setExpiration(expData);

    }
    /**
     *  生成加密后的密钥
     *  @param
     *  @return javax.crypto.SecretKey
     *  mingyifan
     *  2022/2/15 15:00
     */
    public static SecretKey generalKey(){
        byte[] encodedkey = Base64.getDecoder().decode(JwtUtil.JWT_KEY);
        SecretKey key = new SecretKeySpec(encodedkey,0,encodedkey.length,"AES");
        return key;
    }

    public static Claims parseJWT(String jwt){
        SecretKey secretKey = generalKey();
        return Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(jwt)
                .getBody();
    }


    public static void main(String[] args) {
        String jwt = createJWT("123");
        System.out.println(jwt);
        Claims claims = parseJWT("eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI0YjI3NGNmMjI3OWU0MGE1YWRlYjRkYjhkZDUwMWQ1MCIsInN1YiI6IntcImFjY291bnROb25FeHBpcmVkXCI6dHJ1ZSxcImFjY291bnROb25Mb2NrZWRcIjp0cnVlLFwiYXV0aG9yaXRpZXNcIjpbXSxcImNyZWRlbnRpYWxzTm9uRXhwaXJlZFwiOnRydWUsXCJlbmFibGVkXCI6dHJ1ZSxcInBhc3N3b3JkXCI6XCIkMmEkMTAkOTRnc0M2OWZ0ak91SUQwRVdZMmFzLk9taHF2Tm9QbTQyWjhGY2dOTklyZ2t4R2ZZcUxwU0tcIixcInByZW1pc3Npb25zXCI6W10sXCJ1c2VyXCI6e1wiYWxsR2FtZXNcIjoyNixcImlkXCI6XCIxXCIsXCJpc0pvaW5SYW5rTGlzdFwiOjAsXCJwYXNzd29yZFwiOlwiJDJhJDEwJDk0Z3NDNjlmdGpPdUlEMEVXWTJhcy5PbWhxdk5vUG00Mlo4RmNnTk5JcmdreEdmWXFMcFNLXCIsXCJ1c2VybmFtZVwiOlwiMTIzXCIsXCJ3aW5HYW1lc1wiOjE2LFwid2luUGVyY2VudGFnZVwiOjYxLjU0fSxcInVzZXJuYW1lXCI6XCIxMjNcIn0iLCJpc3MiOiJzZyIsImlhdCI6MTY0NjcxMDM2MywiZXhwIjoxNjQ3MzE1MTYzfQ.3Tnibz3JUPcExPYbIbHyKdHz5wOCcN7o9M1DC5mWBDM");
        LoginUser jsonObject = JSON.parseObject(claims.getSubject(), LoginUser.class);

        System.out.println(claims.getSubject());
    }
}
